package com.slipper.system.codeless.service;

import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.constants.Constants;
import com.slipper.core.cache.CacheKey;
import com.slipper.core.cache.CacheUtil;
import com.slipper.core.message.MessageUtil;
import com.slipper.core.message.Topic;
import com.slipper.util.Tool;
import com.slipper.system.codeless.bo.DataFormModelBO;
import com.slipper.system.codeless.bo.DataModelBO;
import com.slipper.system.codeless.dao.DataFormModelDao;
import com.slipper.util.UUID;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.codeless.dao.DataFormDao;
import com.slipper.system.codeless.bo.DataFormBO;

import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;

@Service
@ReadTransactional
public class DataFormService {
    @Resource
    private DataFormDao dataFormDao;
    @Resource
    private DataFormModelDao dataFormModelDao;
    @Resource
    private DataFormModelService dataFormModelService;
    @Resource
    private DataFormFieldService dataFormFieldService;
    @Resource
    private DataFormAutofillService dataFormAutofillService;
    @Resource
    private DataFormDisplayService dataFormDisplayService;

    public DataFormBO queryBy(String id) {
        if (Tool.isBlank(id)) {
            return null;
        }

        DataFormBO dataForm = CacheUtil.get(CacheKey.DataForm.PREFIX + id, DataFormBO.class);
        if (dataForm == null) {
            dataForm = dataFormDao.queryBy(id);
            dataForm.setModelList(dataFormModelService.queryByFormId(id));
            dataForm.setAutofillList(dataFormAutofillService.queryByFormId(id));
            dataForm.setDisplayList(dataFormDisplayService.queryByFormId(id));
            CacheUtil.set(CacheKey.DataForm.PREFIX + id, dataForm, 60 * 60);
        }
        return dataForm;
    }
    
    public List<DataFormBO> queryList(DataFormBO bo) {
        return dataFormDao.queryList(bo);
    }
    
    public PageInfo<DataFormBO> queryPage(DataFormBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(dataFormDao.queryList(bo));
    }
    
    @WriteTransactional
    public int save(DataFormBO bo) {
        if (Tool.isBlank(bo.getDefaultForm())) {
            bo.setDefaultForm(Constants.NO);
        }

        int result = 0;
        if (Tool.isNotBlank(bo.getId())) {
            bo.setUpdateTime(System.currentTimeMillis());
            result += dataFormDao.update(bo);
        } else {
            bo.setId(UUID.getUUID());
            bo.setUpdateTime(System.currentTimeMillis());
            bo.setCreateTime(System.currentTimeMillis());
            result += dataFormDao.insert(bo);
        }

        result += dataFormModelService.save(bo.getId(), bo.getModelList(), bo.getCreateId());
        result += dataFormAutofillService.save(bo.getId(), bo.getAutofillList(), bo.getCreateId());
        result += dataFormDisplayService.save(bo.getId(), bo.getDisplayList(), bo.getCreateId());

        CacheUtil.remove(CacheKey.DataForm.PREFIX + bo.getId());
        MessageUtil.publish(Topic.DATA_FORM_CHANGE);

        return result;
    }

    @WriteTransactional
    public void saveList(List<DataFormBO> list) {
        if (list == null) return;

        list.forEach(item -> {
            if (dataFormDao.queryBy(item.getId()) != null) {
                item.setUpdateTime(System.currentTimeMillis());
                dataFormDao.update(item);
            } else {
                item.setUpdateTime(System.currentTimeMillis());
                item.setCreateTime(System.currentTimeMillis());
                dataFormDao.insert(item);
            }
            CacheUtil.remove(CacheKey.DataForm.PREFIX + item.getId());
        });
    }

    @WriteTransactional
    public void createDefault(DataModelBO bo) {
        if (dataFormDao.queryByDefault(bo.getId()) > 0) {
            return;
        }

        DataFormBO form = new DataFormBO();
        form.setId(UUID.getUUID());
        form.setModelId(bo.getId());
        form.setName(bo.getName() + "(默认表单)");
        form.setLayoutType("自动");
        form.setShowModel("普通");
        form.setDefaultForm(Constants.YES);
        form.setUpdateId(bo.getUpdateId());
        form.setCreateId(bo.getCreateId());
        form.setUpdateTime(System.currentTimeMillis());
        form.setCreateTime(System.currentTimeMillis());
        dataFormDao.insert(form);

        DataFormModelBO formModel = new DataFormModelBO();
        formModel.setId(UUID.getUUID());
        formModel.setFormId(form.getId());
        formModel.setName("");
        formModel.setLabelAlign("居右");
        formModel.setLabelWidth(120);
        formModel.setOrdinal(1);
        formModel.setUpdateId(bo.getUpdateId());
        formModel.setCreateId(bo.getCreateId());
        formModel.setUpdateTime(System.currentTimeMillis());
        formModel.setCreateTime(System.currentTimeMillis());
        dataFormModelDao.insert(formModel);

        dataFormFieldService.createDefault(formModel.getId(), bo);
    }

    @WriteTransactional
    public void deleteByModelId(String modelId) {
        if (Tool.isBlank(modelId)) {
            return;
        }

        DataFormBO qo = new DataFormBO();
        qo.setModelId(modelId);
        dataFormDao.queryList(qo).forEach(this::delete);
    }

    @WriteTransactional
    public int delete(DataFormBO bo) {
        if (Tool.isBlank(bo.getId())) {
            return 0;
        }

        dataFormModelService.deleteByFormId(bo.getId());
        dataFormAutofillService.deleteByFormId(bo.getId());
        dataFormDisplayService.deleteByFormId(bo.getId());
        int result = dataFormDao.delete(bo.getId());
        CacheUtil.remove(CacheKey.DataForm.PREFIX + bo.getId());
        return result;
    }

    @WriteTransactional
    public int copy(DataFormBO bo) {
        if (Tool.isBlank(bo.getId())) {
            return 0;
        }

        // 复制 DataFormBO
        DataFormBO newForm = dataFormDao.queryBy(bo.getId());
        if (newForm == null) {
            return 0;
        }

        newForm.setId(UUID.getUUID());
        newForm.setName(newForm.getName() + "_复制");
        newForm.setDefaultForm(Constants.NO);
        newForm.setUpdateId(bo.getUpdateId());
        newForm.setCreateId(bo.getCreateId());
        newForm.setUpdateTime(System.currentTimeMillis());
        newForm.setCreateTime(System.currentTimeMillis());
        dataFormDao.insert(newForm);

        // 复制 DataFormModel
        dataFormModelService.copyByFormId(bo.getId(), newForm.getId(), bo.getCreateId());
        dataFormAutofillService.copyByFormId(bo.getId(), newForm.getId(), bo.getCreateId());
        dataFormDisplayService.copyByFormId(bo.getId(), newForm.getId(), bo.getCreateId());
        return 1;
    }

    public List<DataFormBO> queryListByModelIds(String[] modelIds) {
        return dataFormDao.queryListByModelIds(modelIds);
    }
}
